package com.whpost.service.service.stamp;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.whpost.service.config.Wdpz;
import com.whpost.service.dao.stamp.*;
import com.whpost.service.dao.t.TDelDao;
import com.whpost.service.dao.wx.TWxOrderDao;
import com.whpost.service.entity.stamp.*;
import com.whpost.service.entity.t.TCzy;
import com.whpost.service.entity.tools.ListInfo;
import com.whpost.service.entity.tools.PageInfo;
import com.whpost.service.entity.tools.ResultInfo;
import com.whpost.service.entity.wx.TWxOrder;
import com.whpost.service.excel.stamp.MxEntity;
import com.whpost.service.service.BaseServices;
import com.whpost.service.service.stamp.h5.WxPay;
import com.whpost.service.service.t.FileService;
import com.whpost.service.service.t.TApiNonceService;
import com.whpost.service.tools.ToolBean;
import com.whpost.service.tools.Url;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.net.URL;
@Service
public class StampCardOrderMxServices extends BaseServices {

    @Resource
    private StampXmMapper stampXmMapper;
    @Resource
    private StampHdMapper stampHdMapper;
    @Resource
    private StampHdLxMapper stampHdLxMapper;
    @Resource
    private TApiNonceService tApiNonceService;
    @Resource
    private Wdpz wdpz;
    @Resource
    private FileService fileService;
    @Resource
    private StampCardMapper stampCardMapper;
    @Resource
    private StampCardOrderMapper stampCardOrderMapper;
    @Resource
    private TDelDao tDelDao;
    @Resource
    private TWxOrderDao tWxOrderDao;
    @Resource
    private StampCardOrderZipMapper stampCardOrderZipMapper;
    @Resource
    private StampCardOrderZipMxMapper stampCardOrderZipMxMapper;
    @Resource
    private StampCardOrderMxMapper stampCardOrderMxMapper;

    @Override
    public ResultInfo query(String loginId, Map<String, Object> map) {
        JSONObject jsonObject = getData(map,loginId);
        if (StringUtils.isEmpty(loginId)){
            return new ResultInfo(500,"用户信息丢失！",null);
        }else{
            String curpage = "",pagesize="",xmxx="",sffk="",sjh="",sfxz="",sftk="",zbid="";
            TCzy tCzy = gettCzyDao().selectById(loginId);
            if (jsonObject.containsKey("curpage")) {
                curpage = jsonObject.getString("curpage");
            }
            if (jsonObject.containsKey("pagesize")) {
                pagesize = jsonObject.getString("pagesize");
            }
            if (jsonObject.containsKey("xmxx")) {
                xmxx = jsonObject.getString("xmxx");
            }
            if (jsonObject.containsKey("sffk")) {
                sffk = jsonObject.getString("sffk");
            }
            if (jsonObject.containsKey("sjh")) {
                sjh = jsonObject.getString("sjh");
            }
            if (jsonObject.containsKey("sfxz")) {
                sfxz = jsonObject.getString("sfxz");
            }
            if (jsonObject.containsKey("sftk")) {
                sftk = jsonObject.getString("sftk");
            }
            if (jsonObject.containsKey("zbid")) {
                zbid = jsonObject.getString("zbid");
            }

            if (StringUtils.isEmpty(sfxz)) sfxz="0";
            if (StringUtils.isEmpty(sffk)) sffk="1";
            if (StringUtils.isEmpty(sftk)) sftk="0";

            if (StringUtils.isEmpty(curpage)) curpage = "1";
            if (StringUtils.isEmpty(pagesize)) pagesize = "10";

            IPage<StampCardOrderMx> stampCardOrderMxIPage =null;
            QueryWrapper<StampCardOrderMx> queryWrapper = new QueryWrapper<>();

            Page<StampCardOrderMx> page = new Page<>( Integer.parseInt(curpage),  Integer.parseInt(pagesize));
            List<StampXm> stampXmList = new ArrayList<>();
            if (!StringUtils.isEmpty(zbid)){
                queryWrapper.eq("stamp_card_order_id",zbid);
            }else{
                //找出操作员所在机构维护的项目
                stampXmList = stampXmMapper.selectList(new QueryWrapper<StampXm>().eq("t_xzjg_id",tCzy.getXzjgId()).eq("state","1"));
                String ids = "";
                // 使用增强的 for 循环遍历原始列表
                for (StampXm stampXm : stampXmList) {
                    ids+=String.valueOf(stampXm.getId())+",";
                }
                if (ids.length()>0) {
                    ids=ids.substring(0,ids.length()-1);
                    ids = "("+ids+")";
                }else{
                    return new ResultInfo(500,"没有任何数据！",null);
                }

                if (!"3".equals(sfxz)){
                    queryWrapper.eq("sfxz",sfxz);
                }
                queryWrapper.eq("state","1");
                String str="";
                String post_sjh="";
                if (!StringUtils.isEmpty(sjh)){
                    try {
                        post_sjh = Url.encrypt(sjh);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    str = " and stamp_card_order_id in (select id from stamp_card_order where lxdh='"+post_sjh+"' or lxdh_jsm like '%"+sjh+"%')";
                }

                if (StringUtils.isEmpty(xmxx)) {
                    if (!"3".equals(sffk)){
                        queryWrapper.apply(" stamp_card_order_id in (select id from stamp_card_order where scbz='0' and isfk='"+sffk+"' and istk='"+sftk+"' and hd_id in (select id from stamp_hd where xm_id in "+ids+") "+str+")");
                    }else{
                        queryWrapper.apply(" stamp_card_order_id in (select id from stamp_card_order where scbz='0' and istk='"+sftk+"' and hd_id in (select id from stamp_hd where xm_id in "+ids+") "+str+")");
                    }
                }else{
                    if (!"3".equals(sffk)){
                        queryWrapper.apply(" stamp_card_order_id in (select id from stamp_card_order where scbz='0' and istk='"+sftk+"' and isfk='"+sffk+"' and hd_id in (select id from stamp_hd where xm_id="+xmxx+")  "+str+")");
                    }else{
                        queryWrapper.apply(" stamp_card_order_id in (select id from stamp_card_order where scbz='0' and istk='"+sftk+"' and hd_id in (select id from stamp_hd where xm_id="+xmxx+")  "+str+")");
                    }
                }
            }
            queryWrapper.orderByDesc("id");
            queryWrapper.orderByDesc("zhxzrq");


            stampCardOrderMxIPage = stampCardOrderMxMapper.getStampCardOrderMxLPage(page,queryWrapper);

            ListInfo<StampCardOrderMx> stampCardOrderMxListInfo = new ListInfo<>();
            PageInfo pageInfo = new PageInfo();
            pageInfo.setTotal(stampCardOrderMxIPage.getTotal());
            pageInfo.setCurPage(stampCardOrderMxIPage.getCurrent());
            pageInfo.setPageSize(stampCardOrderMxIPage.getSize());
            pageInfo.setPageTotal(stampCardOrderMxIPage.getPages());

            stampCardOrderMxListInfo.setPageInfo(pageInfo);
            stampCardOrderMxListInfo.setListInfo(stampCardOrderMxIPage.getRecords());
            stampCardOrderMxListInfo.setUserId(loginId);

            //查询条件的值
            Map<String,Object> cxtjMap = new HashMap<>();
            cxtjMap.put("sjh",sjh);
            cxtjMap.put("xmxx",xmxx);
            cxtjMap.put("sffk",sffk);
            cxtjMap.put("sfxz",sfxz);
            cxtjMap.put("stampXmList",stampXmList);

            //返回前端的内容
            Map<String,Object> rtnMap = new HashMap<>();
            rtnMap.put("cxjg",stampCardOrderMxListInfo);
            rtnMap.put("cxtj",cxtjMap);

            ResultInfo resultInfo = new ResultInfo(0, "成功返回！",rtnMap);
            return backRtn(resultInfo,loginId);
        }
    }

    public String xztp(String loginId, String id, HttpServletResponse httpServletResponse) throws IOException {
        if (StringUtils.isEmpty(loginId)){
            return "用户信息丢失！";
        }else{
            StampCardOrderMx stampCardOrderMx = new StampCardOrderMx();
            stampCardOrderMx = stampCardOrderMxMapper.getById(Long.parseLong(id));

            StampCard stampCard = new StampCard();
            stampCard = stampCardOrderMx.getStampCard();

            String zst = stampCard.getWjlj();

            String ysb_wjm = stampCardOrderMx.getId()+"_"+stampCard.getStampHd().getStampXm().getName()+"_"+stampCardOrderMx.getStampCardOrder().getLxr()+"_"+stampCardOrderMx.getStampCardOrder().getTHyxx().getName()+".jpg";

            File readFile = new File(zst);
            //字节流-用于读文件  这里只是demo用的非缓冲流。实际项目可以用BufferedInputStream。 此功能是读取图片，所以用的字节流。如果是文本的话可以用字符流效率高，具体类看下面注释
            //        BufferedReader bufferedReader = new BufferedReader(new FileReader(readFile));//字符流
            FileInputStream fileInputStream = new FileInputStream(readFile);//字节流
            //设置文件下载方式
            httpServletResponse.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(ysb_wjm,"utf-8"));
            //获取servlet响应输出字节流
            //        PrintWriter writer = response.getWriter();//字符流
            ServletOutputStream outputStream = httpServletResponse.getOutputStream(); //字节流

            //流数据交换，每次交换10k数据大小 （1024k = 1m）
            byte[] bytes = new byte[1024*10];
            int read;
            do {
                read = fileInputStream.read(bytes);
                outputStream.write(bytes,0,read);
            }while (-1 != read);

            //关闭资源
            IOUtils.closeQuietly(fileInputStream);
            IOUtils.closeQuietly(outputStream);

            return "下载成功！";

        }
    }

    @Transactional
    public ResultInfo zip(String loginId, Map<String, Object> map) throws Exception {
        JSONObject jsonObject = getData(map,loginId);
        if (StringUtils.isEmpty(loginId)){
            return new ResultInfo(500,"用户信息丢失！",null);
        }else{
            String ids = "",token="";
            if (jsonObject.containsKey("ids")) {
                ids = jsonObject.getString("ids");
            }
            if (jsonObject.containsKey("token")) {
                token = jsonObject.getString("token");
            }
            String [] code = ids.split(",");
            StampCardOrderMx stampCardOrderMx = new StampCardOrderMx();

            TCzy tCzy = gettCzyDao().getCzyById(loginId);
            TCzy tCzyDel = new TCzy();

            String rq = ToolBean.getTodayStr("yyyyMMddHHmmss");

            // ZIP文件的输出路径
            String os = System.getProperty("os.name");
            String zipOutputPath = "";
            String excel_name = "";
            if(os!=null&&os.contains("Windows")){
                //System.out.println("Windows");
                zipOutputPath="d:\\stamp\\"+rq+".zip";
                excel_name="d:\\stamp\\"+rq+".xls";
            }else{
                //linux
                zipOutputPath = "/home/stamp/zip/"+rq+".zip";
                excel_name = "/home/stamp/zip/"+rq+".xls";
            }
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipOutputPath));
            StampCard stampCard = new StampCard();

            //先写一个压缩主表
            StampCardOrderZip stampCardOrderZip = new StampCardOrderZip();
            stampCardOrderZip.setTCzyId(tCzy.getId());
            stampCardOrderZip.setAddRq(ToolBean.getToday());
            stampCardOrderZip.setTXzjgId(tCzy.getXzjgId());
            stampCardOrderZipMapper.insert(stampCardOrderZip);

            StampCardOrderZipMx stampCardOrderZipMx = new StampCardOrderZipMx();


            //生成excel
            List<MxEntity> mxEntityList = new ArrayList<>();
            MxEntity mxEntity = new MxEntity();

            for(int i=0;i<code.length;i++){
                ToolBean.info("code:"+code[i]);
                if (code[i].equals("")) {
                    continue;
                }

                String id = code[i];

                stampCardOrderMx = new StampCardOrderMx();
                stampCardOrderMx = stampCardOrderMxMapper.getById(Long.parseLong(id));

                stampCard = new StampCard();
                stampCard = stampCardOrderMx.getStampCard();

                if (null==stampCard){
                    //明细写备注
                    stampCardOrderMx.setSfxz("2");
                    stampCardOrderMx.setZhxzrq(rq);
                    stampCardOrderMx.setZhxzrz("未找到照片记录!跳出循环");
                    stampCardOrderMxMapper.updateById(stampCardOrderMx);

                    //压缩明细也写一条失败的文件记录
                    stampCardOrderZipMx = new StampCardOrderZipMx();
                    stampCardOrderZipMx.setZbId(stampCardOrderZip.getId());
                    stampCardOrderZipMx.setStampCardOrderMxId(stampCardOrderMx.getId());
                    stampCardOrderZipMx.setState("2");
                    stampCardOrderZipMx.setMemo("未找到照片记录!跳出循环");
                    stampCardOrderZipMxMapper.insert(stampCardOrderZipMx);
                    continue;
                }

                ToolBean.info("mx["+stampCardOrderMx.getId()+"]的card["+stampCard.getId()+"]开始打包");

                String lj = stampCard.getWjlj();
                ToolBean.info("card["+stampCard.getId()+"]准备往zip添加文件："+lj);
                File fileToCompress1 = new File(lj);
                if (!fileToCompress1.exists()){
                    ToolBean.info("card["+stampCard.getId()+"]准备往zip添加文件："+lj+",不存在，跳过！");
                    stampCardOrderMx.setSfxz("2");
                    stampCardOrderMx.setZhxzrq(rq);
                    stampCardOrderMx.setZhxzrz("文件不存在!");
                    stampCardOrderMxMapper.updateById(stampCardOrderMx);

                    //压缩明细也写一条失败的文件记录
                    stampCardOrderZipMx = new StampCardOrderZipMx();
                    stampCardOrderZipMx.setZbId(stampCardOrderZip.getId());
                    stampCardOrderZipMx.setStampCardOrderMxId(stampCardOrderMx.getId());
                    stampCardOrderZipMx.setState("2");
                    stampCardOrderZipMx.setMemo("文件不存在！");
                    stampCardOrderZipMxMapper.insert(stampCardOrderZipMx);
                    continue;
                }
                FileInputStream fileIn1 = new FileInputStream(fileToCompress1);
                BufferedInputStream bufferedIn1 = new BufferedInputStream(fileIn1);
                //压缩包里面的文件名
                //String ysb_wjm = stampCardOrderMx.getId()+"_"+stampCard.getStampHd().getStampXm().getName()+".jpg";
                String ysb_wjm = stampCardOrderMx.getId()+"_"+stampCard.getStampHd().getStampXm().getName()+"_"+stampCardOrderMx.getStampCardOrder().getLxr()+"_"+stampCardOrderMx.getStampCardOrder().getTHyxx().getName()+".jpg";
                ToolBean.info("card["+stampCard.getId()+"]准备往zip添加文件："+lj+",添加文件名：["+ysb_wjm+"]");
                ZipEntry zipEntry1 = new ZipEntry(ysb_wjm);
                zipOut.putNextEntry(zipEntry1);
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = bufferedIn1.read(buffer)) != -1) {
                    zipOut.write(buffer, 0, bytesRead);
                }
                bufferedIn1.close();

                stampCardOrderMx.setSfxz("1");
                stampCardOrderMx.setZhxzrz("已加入打包文件!");
                stampCardOrderMx.setZhxzrq(rq);
                stampCardOrderMxMapper.updateById(stampCardOrderMx);

                stampCardOrderZipMx = new StampCardOrderZipMx();
                stampCardOrderZipMx.setZbId(stampCardOrderZip.getId());
                stampCardOrderZipMx.setStampCardOrderMxId(stampCardOrderMx.getId());
                stampCardOrderZipMx.setState("1");
                stampCardOrderZipMx.setMemo("已加入打包文件！");
                stampCardOrderZipMxMapper.insert(stampCardOrderZipMx);

                //写进excel
                mxEntity = new MxEntity();
                mxEntity.setLsh(String.valueOf(stampCardOrderMx.getId()));
                mxEntity.setHdmc(stampCard.getStampHd().getName());
                mxEntity.setDbwjm(ysb_wjm);
                mxEntity.setSjr(stampCardOrderMx.getStampCardOrder().getLxr());
                mxEntity.setSjrdz(stampCardOrderMx.getStampCardOrder().getFullDz());
                String dh = stampCardOrderMx.getStampCardOrder().getLxdh();
                if (!org.apache.commons.lang3.StringUtils.isEmpty(dh)){
                    dh = Url.decrypt(dh);
                }
                mxEntity.setSjrdh(dh);

                //这里需要一个可以访问的展示图片的地址
                mxEntity.setImage(fileToByteArray(stampCard.getWjljZs()));

                mxEntityList.add(mxEntity);

                ToolBean.info("card["+stampCard.getId()+"]准备往zip添加文件完成："+lj);
            }

            if (toExcel(excel_name,mxEntityList)){

                ToolBean.info("card["+stampCard.getId()+"]准备往zip添加文件EXCEL");
                File excel_file = new File(excel_name);
                if (!excel_file.exists()){
                    ToolBean.info("card["+stampCard.getId()+"]准备往zip添加文件EXCEL："+excel_name+",不存在，跳过！");
                }else{
                    FileInputStream fileIn1 = new FileInputStream(excel_file);
                    BufferedInputStream bufferedIn1 = new BufferedInputStream(fileIn1);
                    //压缩包里面的文件名
                    String ysb_wjm = "明细.xls";
                    ToolBean.info("card["+stampCard.getId()+"]准备往zip添加文件："+excel_name+",添加文件名：["+ysb_wjm+"]");
                    ZipEntry zipEntry1 = new ZipEntry(ysb_wjm);
                    zipOut.putNextEntry(zipEntry1);
                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    while ((bytesRead = bufferedIn1.read(buffer)) != -1) {
                        zipOut.write(buffer, 0, bytesRead);
                    }
                    bufferedIn1.close();
                }
            }


            Long sl = stampCardOrderZipMxMapper.selectCount(new QueryWrapper<StampCardOrderZipMx>().eq("zb_id",stampCardOrderZip.getId()));

            stampCardOrderZip.setZsl(sl);
            stampCardOrderZip.setWjlj(zipOutputPath);

            stampCardOrderZipMapper.updateById(stampCardOrderZip);

            zipOut.close();

            return new ResultInfo(7,"打包成功！",ToolBean.getEncode(stampCardOrderZip.getId()));
        }
    }


    /**
     * 明细导出带图片
     */
    public boolean toExcel(String fileName, List<MxEntity> mxEntityList) {
        try {
            // 写入数据
            EasyExcel.write(fileName, MxEntity.class).sheet().doWrite(mxEntityList);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            ToolBean.info("toExcel发生错误！"+e.toString());
            return false;
        }
    }

    public String xzzip(String loginId, String id, HttpServletResponse httpServletResponse) throws IOException, ParseException {
        if (StringUtils.isEmpty(loginId)){
            return "用户信息丢失！";
        }else{
            if (StringUtils.isEmpty(id)){
                return "文件丢失！";
            }
            id = ToolBean.getDecode(id);

            StampCardOrderZip stampCardOrderZip = new StampCardOrderZip();
            stampCardOrderZip = stampCardOrderZipMapper.selectById(Long.parseLong(id));

            if (!stampCardOrderZip.getTCzyId().equals(Long.parseLong(loginId))){
                return "非自己生成的文件！";
            }

            String zst = stampCardOrderZip.getWjlj();
            String rq = ToolBean.getTodayStr("yyyyMMddHHmmss");
            File readFile = new File(zst);
            //字节流-用于读文件  这里只是demo用的非缓冲流。实际项目可以用BufferedInputStream。 此功能是读取图片，所以用的字节流。如果是文本的话可以用字符流效率高，具体类看下面注释
            //        BufferedReader bufferedReader = new BufferedReader(new FileReader(readFile));//字符流
            FileInputStream fileInputStream = new FileInputStream(readFile);//字节流
            //设置文件下载方式
            httpServletResponse.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode("打包图片_"+rq+".zip","utf-8"));
            //获取servlet响应输出字节流
            //        PrintWriter writer = response.getWriter();//字符流
            ServletOutputStream outputStream = httpServletResponse.getOutputStream(); //字节流

            //流数据交换，每次交换10k数据大小 （1024k = 1m）
            byte[] bytes = new byte[1024*10];
            int read;
            do {
                read = fileInputStream.read(bytes);
                outputStream.write(bytes,0,read);
            }while (-1 != read);

            //关闭资源
            IOUtils.closeQuietly(fileInputStream);
            IOUtils.closeQuietly(outputStream);

            return "下载成功！";

        }
    }

    public static byte[] fileToByteArray(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath);
             ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}
